/*
 * KineticSolver.h
 *
 *  Created on: 28 Jul 2011
 *      Author: Allan
 */

#ifndef KINETICSOLVER_H_
#define KINETICSOLVER_H_

// Eigen includes
#include <Eigen/Core>
using namespace Eigen;

// GeoReact includes
#include <Core/CannonicalSystem.h>
#include <Core/KineticProblem.h>
#include <Core/TotalEquilibriumSolver.h>
#include <Numerics/OdeSolver.h>

struct KineticStatus
{
	/// The current time in the calculation
	double t;
	
	/// The current time step been used in the calculation
	double dt;
	
	/// The indicator of completion of the calculation
	bool finished;
};

class KineticSolver
{
public:
	KineticSolver();
	
	KineticSolver(const CannonicalSystem& cannonical_system);

	void
	Initialiaze(const CannonicalSystem& cannonical_system);
	
	void
	SetMinimumTimeStep(double dt_min);
	
	void
	SetMaximumTimeStep(double dt_max);
	
	void
	SetAlgorithm(OdeAlgorithm algorithm);
	
	void
	SetControlSolution(double eps_abs, double eps_rel);
	
	const double
	GetMinimumTimeStep() const;
	
	const double
	GetMaximumTimeStep() const;
	
	const OdeAlgorithm
	GetAlgorithm() const;
	
	const bool
	TotalEquilibrate(const VectorXd& ujnk, double T, double P, VectorXd& n);
	
	const bool
	ReactStep(KineticStatus& status, double tend, double T, double P, VectorXd& n);
	
	void
	React(double tbegin, double tend, double T, double P, VectorXd& n);
	
	friend class KineticProblem;
	
private:
	/// The cannonical system
	CannonicalSystem cannonical_system;
	
	/// The ODE solver
	OdeSolver ode_solver;
	
	/// The total equilibrium solver
	TotalEquilibriumSolver total_equilibrium_solver;
	
	/// The minimum and maximum allowed time steps
	double dt_min, dt_max;
	
	/// The algorithm used for the calculation
	OdeAlgorithm algorithm;
};

#endif /* KINETICSOLVER_H_ */
